"""
@Author : 合肥一元数智教育科技有限公司
@Date :  2025/3/19 8:42
@Description : 群聊天室服务端
1. 抽取服务端类
   1.1 属性   socket  ip  port  max_connection  socket容器 存储所有已连接客户端的socket  列表
   1.2 操作   群发消息
"""
import socket
import threading


class ChatServer:
    def __init__(self, ip, port, max_connection):
        self.ip = ip
        self.port = port
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server_socket.bind((self.ip, self.port))
        # 设置连接最大挂起个数
        self.server_socket.listen(max_connection)
        # 创建容器 存储所有已连接客户端的socket
        self.all_client_sockets = []

    # 群发消息
    def handle_client(self, client_socket: socket, client_address: tuple):
        try:
            while True:
                client_message = client_socket.recv(1024).decode('utf-8')
                if client_message:
                    print(f'{client_address}消息: {client_message}')
                    # 群发信息
                    for one_client_socket in self.all_client_sockets:
                        # 信息不要重复发送给自己
                        if one_client_socket != client_socket:
                            one_client_socket.send(client_message.encode('utf-8'))
        except ConnectionResetError:
            # 剔除已经离线的客户端
            self.all_client_sockets.remove(client_socket)
            print(f'{client_address}客户端离线...')

    # 启动服务端
    def start_server(self):
        print('服务端成功启动,等待客户端连接...')
        while True:
            # 监听客户端的连接  阻塞
            client_socket, client_address = self.server_socket.accept()
            # 输出连接的用户信息
            print(f'{client_address}客户端连接了...')
            # 保存客户端的socket
            self.all_client_sockets.append(client_socket)
            # 创建线程  开始与客户端进行会话
            threading.Thread(target=self.handle_client, args=(client_socket, client_address)).start()


if __name__ == '__main__':
    try:
        chat_server = ChatServer(ip='127.0.0.1', port=9999, max_connection=5)
        chat_server.start_server()
    except Exception as e:
        print('服务启动失败:', e)
